﻿using MahApps.Metro.Controls;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows;
using System.Windows.Controls.Primitives;

namespace Com.Lancetinc.Evs.Controls
{
    /// <summary>
    /// 封装FlyoutsControl以便统一通知打开/关闭事件
    /// </summary>
    public class LevsFlyoutsControl : FlyoutsControl
    {
        public event EventHandler IsOpenChanged;

        #region DisableMask
        public static readonly DependencyProperty DisableMaskProperty
            = DependencyProperty.RegisterAttached(
                "DisableMask",
                typeof(bool),
                typeof(LevsFlyoutsControl),
                new UIPropertyMetadata(false));

        public static bool GetDisableMask(UIElement element)
        {
            return (bool)element.GetValue(DisableMaskProperty);
        }

        public static void SetDisableMask(UIElement element, bool value)
        {
            element.SetValue(DisableMaskProperty, value);
        }

        #endregion

        /// <summary>
        /// 判断是否有打开的Flyouts
        /// </summary>
        public bool HasOpenedFlyout => (_lastFlyouts ?? GetFlyouts()).Any(x => x.IsOpen);

        public LevsFlyoutsControl()
        {
            this.ItemContainerGenerator.ItemsChanged += ItemContainerGenerator_ItemsChanged;
        }

        private void ItemContainerGenerator_ItemsChanged(object sender, ItemsChangedEventArgs e)
        {
            RegisterFlyoutEvents(GetFlyouts().ToArray());
        }

        public IEnumerable<Flyout> GetFlyouts()
        {
            foreach (var item in this.Items)
            {
                var flyout = this.GetFlyout(item);
                if (flyout is not null)
                {
                    yield return flyout;
                }
            }
        }

        private void Flyout_IsOpenChanged(object sender, RoutedEventArgs e)
        {
            IsOpenChanged?.Invoke(sender, e);
        }

        private Flyout GetFlyout(object item)
        {
            if (item is Flyout flyout)
            {
                return flyout;
            }

            return this.ItemContainerGenerator.ContainerFromItem(item) as Flyout;
        }

        private Flyout[] _lastFlyouts = null;
        private void RegisterFlyoutEvents(Flyout[] flyouts)
        {
            foreach (var flyout in flyouts)
            {
                flyout.IsOpenChanged -= Flyout_IsOpenChanged;
                flyout.IsOpenChanged += Flyout_IsOpenChanged;
            }

            if (_lastFlyouts != null)
            {
                foreach (var removedFlyout in _lastFlyouts.Except(flyouts))
                {
                    removedFlyout.IsOpenChanged -= Flyout_IsOpenChanged;
                }
            }
            _lastFlyouts = flyouts;
        }
    }
}